<template>
  <a-table
    ref="ATable"
    v-bind="$attrs"
    :row-key="rowKey"
    :loading="loading"
    :data-source="tableData"
    :pagination="tablePagination"
    :bordered="true"
    :row-class-name="(_record, index) => (index % 2 === 1 ? 'antd-table-striped' : null)"
    class="antd-table"
    style="width: 100%; height: 100%"
    @change="onTableChange"
  >
    <a-table-column v-for="item of tableColumns" v-bind="item">
      <template v-if="item.scopedSlots && item.scopedSlots.customRender === 'index'" #default="text, scope, index">
        <slot name="index" :text="text" :scope="scope" :index="index + 1">{{ index + 1 }}</slot>
      </template>
      <template v-else #default="text, scope, index">
        <slot
          v-if="item.scopedSlots && item.scopedSlots.customRender"
          :name="item.scopedSlots.customRender"
          :pagination="tablePagination"
          :option="item"
          :text="text"
          :scope="scope"
          :index="index"
        />
        <table-text-tip
          v-else
          :text="typeof item.customRender === 'function' ? item.customRender(text, scope) : text"
          :originalText="item.defaultText"
        />
      </template>
    </a-table-column>
  </a-table>
</template>

<script>
import TableTextTip from './table-text-tip.vue';
import { isBoolean, isNumber } from '../../utils/dataType.js';

export default {
  name: 'antd-table',
  components: { TableTextTip },
  props: {
    api: { type: Function, default: undefined },
    apiParams: { type: Object, default: () => undefined },
    dataSource: { type: Array, default: () => [] },
    columns: { type: Array, default: () => [] },
    rowKey: { type: [String, Function], default: 'id' },
    pagination: { type: [Object, Boolean], default: () => ({}) },
    replacePageFields: { type: Object, default: () => ({}) },
  },
  data() {
    return {
      loading: false,
      tableData: [],
      tablePagination: {
        pageSizeOptions: ['10', '20', '30', '40'],
        showTotal: (total) => `共 ${total} 条`,
        showQuickJumper: false,
        showSizeChanger: false,
        showLessItems: true,
        pageSize: 10,
        current: 1,
        total: 0,
      },
    };
  },
  computed: {
    pageFields() {
      const dft = { pageSize: 'page_size', current: 'page_number' };
      return Object.assign({}, dft, this.replacePageFields);
    },
    tableColumns() {
      return this.columns.map((item) => {
        item = Object.assign({}, item, {
          title: item.title || item.label,
          align: item.align || 'center',
          ellipsis: typeof item.ellipse === 'boolean' ? item.ellipse : true,
          resizable: isNumber(item.width) ? (isBoolean(item.resizable) ? item.resizable : true) : false,
        });
        return item;
      });
    },
  },
  watch: {
    dataSource: {
      immediate: true,
      handler() {
        if (typeof this.api !== 'function' && Array.isArray(this.dataSource)) {
          this.tableData = this.dataSource;
        }
      },
    },
    pagination: {
      immediate: true,
      handler(pagination) {
        this.setTablePagination(pagination);
      },
    },
  },
  created() {},
  methods: {
    load(params) {
      this.setTablePagination({ current: 1 });
      this.getDataAsync(params);
    },
    reload() {
      this.onTableChange();
    },
    onTableChange(pagination) {
      this.setTablePagination(pagination);
      this.getDataAsync();
    },
    getIsShowPagination() {
      return this.pagination !== false && this.pagination !== null;
    },
    setTablePagination(pagination) {
      if (!this.getIsShowPagination()) {
        this.tablePagination = false;
        return false;
      }
      this.tablePagination = Object.assign({}, this.tablePagination, pagination);
    },
    getPageParams() {
      if (!this.getIsShowPagination()) {
        return {};
      }
      return {
        [this.pageFields.current]: this.tablePagination.current,
        [this.pageFields.pageSize]: this.tablePagination.pageSize,
      };
    },
    async getDataAsync(params) {
      if (typeof this.api === 'function') {
        params = Object.assign(this.getPageParams(), this.apiParams, params);
        this.loading = true;
        const res = await this.api(params).catch(() => {
          this.loading = false;
        });
        const { data = [], total = 0 } = res || {};
        this.tableData = data;
        if (this.getIsShowPagination()) {
          this.tablePagination = Object.assign({}, this.tablePagination, { total });
        }
        this.loading = false;
      }
    },
  },
};
</script>

<style lang="less"></style>
